package com.iflytek.voicecloud.rtasr.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iflytek.voicecloud.rtasr.service.DBCreate;
import com.iflytek.voicecloud.rtasr.service.RTASRService;
import jakarta.annotation.PostConstruct;
import org.java_websocket.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.BinaryWebSocketHandler;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * WebSocket处理器，用于处理实时语音识别的文本和二进制消息。
 */
@Component
public class RTASRWebSocketHandler extends BinaryWebSocketHandler {

    @Autowired
    private DBCreate dbService; // Spring 自动注入

    // 缓存会话相关的数据
    private final ConcurrentHashMap<String, ByteBuffer> bufferMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, AtomicBoolean> receivingMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, RTASRService.MyWebSocketClient> clientMap = new ConcurrentHashMap<>(); // 3. 新增客户端缓存
    private final ConcurrentHashMap<String, CompletableFuture<RTASRService.MyWebSocketClient>> futureMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, UUID> interviewIdMap = new ConcurrentHashMap<>();
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final ConcurrentHashMap<String, Integer> questionOrderMap = new ConcurrentHashMap<>();

    // 新增一个 Map 来记录连接建立时间
    private final ConcurrentHashMap<String, LocalDateTime> sessionStartTimeMap = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String sessionId = session.getId();
        LocalDateTime now = LocalDateTime.now();
        sessionStartTimeMap.put(sessionId, now);
        super.afterConnectionEstablished(session);
    }

    //前端只发送文本数据不会创建讯飞的WebSocket连接
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        String sessionId = session.getId();
        try {
            JsonNode jsonNode = objectMapper.readTree(message.getPayload());

            // 处理 interviewId 字段
            if (jsonNode.has("interviewId")) {
                String interviewIdStr = jsonNode.get("interviewId").asText();
                UUID interviewId = UUID.fromString(interviewIdStr);
                interviewIdMap.put(sessionId, interviewId);
            }

            // 处理 questionOrder 字段
            if (jsonNode.has("questionOrder")) {
                String orderStr = jsonNode.get("questionOrder").asText();
                int questionOrder = Integer.parseInt(orderStr);
                questionOrderMap.put(sessionId, questionOrder);
            }

            // 处理 Answer 字段，用于文本代码的接收
            if (jsonNode.has("Answer")) {
                String answer = jsonNode.get("Answer").asText();
                System.out.println("✅ Answer received and saved: " + answer);
                UUID interviewId = interviewIdMap.get(sessionId);
                Integer questionOrder = questionOrderMap.get(sessionId);
                LocalDateTime startTime = sessionStartTimeMap.get(sessionId);
                LocalDateTime endTime = LocalDateTime.now();
                dbService.receiveResults(answer , interviewId , startTime, endTime , questionOrder);

                try {
                    dbService.receiveResults(answer, interviewId, startTime, endTime, questionOrder);
                    session.sendMessage(new TextMessage("{\"status\":\"Answer received and processed\"}"));
                    session.close();
                } catch (Exception e) {
                    String errorMessage = "数据库插入失败: " + e.getMessage();
                    System.err.println("❌ 插入失败: " + errorMessage);
                    session.sendMessage(new TextMessage("{\"status\":\"error\", \"message\":\"" + errorMessage + "\"}"));
                }
            }

            session.sendMessage(new TextMessage("{\"status\":\"interviewId and question_order received\"}"));

        } catch (IOException e) {
            System.err.println("Error parsing JSON: " + e.getMessage());
        } catch (IllegalArgumentException e) {
            System.err.println("Invalid UUID or order format: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("Unexpected error: " + e.getMessage());
        }
    }

    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception { // 4. 改为处理二进制消息
        String sessionId = session.getId();
        byte[] payload = message.getPayload().array();

        if (isEndSignal(payload)) {
            System.out.println("✅ 成功识别END信号");

            if (receivingMap.containsKey(sessionId) && receivingMap.get(sessionId).get()) {
                receivingMap.get(sessionId).set(false);
                CompletableFuture<RTASRService.MyWebSocketClient> future = futureMap.get(sessionId);
                if (future != null) {
                    RTASRService.MyWebSocketClient client = future.get();
                    RTASRService.send(client, "{\"end\": true}".getBytes());
                }
                bufferMap.remove(sessionId);
                receivingMap.remove(sessionId);
            }

            // 获取 interviewId 和 questionOrder
            UUID interviewId = interviewIdMap.get(sessionId);
            Integer questionOrder = questionOrderMap.get(sessionId);

            // 获取增强结果
            String lastResult = RTASRService.getLastEnhancedResult(sessionId);

            // 获取开始时间
            LocalDateTime startTime = sessionStartTimeMap.get(sessionId);
            LocalDateTime endTime = LocalDateTime.now();

            if (lastResult != null && interviewId != null && startTime != null) {
                dbService.receiveResults(lastResult, interviewId , startTime, endTime , questionOrder);
                interviewIdMap.remove(sessionId);
            }
        } else {
            if (!receivingMap.containsKey(sessionId)) {
                // 首次接收时初始化缓冲区并创建连接
                bufferMap.put(sessionId, ByteBuffer.allocate(20000));
                receivingMap.put(sessionId, new AtomicBoolean(true));
                RTASRService rtasrService = new RTASRService();

                CompletableFuture<RTASRService.MyWebSocketClient> future = CompletableFuture.supplyAsync(() -> {
                    try {
                        return rtasrService.createWebSocketClient(sessionId, session); // 传入 session
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                });

                futureMap.put(sessionId, future);
            }

            if (receivingMap.get(sessionId).get()) {
                CompletableFuture<RTASRService.MyWebSocketClient> future = futureMap.get(sessionId);
                if (future != null) {
                    RTASRService.MyWebSocketClient client = future.getNow(null);
                    if (client != null) {
                        RTASRService.send(client, payload);
                    } else {
                        session.sendMessage(new TextMessage("连接尚未建立，请稍后再试"));
                    }
                }
            }
        }
    }

    // 新增结束标志判断方法
    private boolean isEndSignal(byte[] data) {
        try {
            String received = new String(data, "UTF-8").trim();
            return "END".equals(received);
        } catch (Exception e) {
            return false;
        }
    }

}